use std::fs::{self, OpenOptions};
use std::io::{Read, Write};
use std::path::PathBuf;

pub struct DistrictData<'a> {
    dir_name: &'a str,
}

impl<'a> DistrictData<'a> {
    pub fn new(name: &str) -> DistrictData {
        DistrictData { dir_name: name }
    }
    pub fn insert_code(&self, code: &str, name: &str) -> std::io::Result<()> {
        if code.len() != 6 || !code.chars().all(|c| c.is_digit(10)) {
            return Err(std::io::Error::new(
                std::io::ErrorKind::InvalidInput,
                "行政区划代码应为6位数字",
            ));
        }

        // 获取省、市、区县代码
        let province_code = &code[0..2];
        let city_code = &code[2..4];
        let mut filename = &code[4..6];

        let mut dir_path = PathBuf::from(self.dir_name);
        dir_path.push(province_code);
        if filename == "00" {
            if city_code != "00" {
                dir_path.push(city_code);
            }
            filename = "index";
        } else {
            dir_path.push(city_code);
        }
        fs::create_dir_all(&dir_path)?;
        let mut file = OpenOptions::new()
            .create(true)
            .write(true)
            .open(dir_path.join(filename))?;
        file.write_all(name.as_bytes())?;
        Ok(())
    }

    pub fn search_code(&self, code: &str) -> Option<(String, String, String)> {
        // 验证代码长度是否为 6 位数字
        if code.len() != 6 || !code.chars().all(|c| c.is_digit(10)) {
            return None;
        }

        let province_code = &code[0..2];
        let city_code = &code[2..4];

        let mut dir_path = PathBuf::from(self.dir_name);
        dir_path.push(province_code);

        let mut province_file = OpenOptions::new()
            .read(true)
            .open(dir_path.join("index"))
            .ok()?;
        let mut province_name = String::new();
        province_file.read_to_string(&mut province_name).ok()?;

        dir_path.push(city_code);

        let mut city_name = String::new();
        let city_file = OpenOptions::new().read(true).open(&dir_path.join("index"));
        match city_file {
            Err(e) => {
                if e.kind() == std::io::ErrorKind::NotFound && city_code == "01" {
                    city_name = "市辖区".to_string();
                } else {
                    return None;
                }
            }
            Ok(mut f) => {
                f.read_to_string(&mut city_name).ok()?;
            }
        }

        let mut district_name = String::new();
        let mut district_file = OpenOptions::new()
            .read(true)
            .open(dir_path.join(&code[4..6]))
            .ok()?;
        district_file.read_to_string(&mut district_name).ok()?;
        Some((province_name, city_name, district_name))
    }
}
